home *** CD-ROM | disk | FTP | other *** search
/ Risc World 5 / Risc World 5.iso / SOFTWARE / Issue5 / PD / DIRSYNC / LegalStuff / ccres / c / Convert < prev    next >
Text File  |  2004-03-20  |  15KB  |  517 lines

  1. /* Convert.c
  2.    $Id: Convert.c,v 1.2 2004/03/20 22:12:23 joty Exp $
  3.  
  4.    Copyright (c) 2003-2004 Dave Appleby / John Tytgat
  5.  
  6.    This file is part of CCres.
  7.  
  8.    CCres is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2 of the License, or
  11.    (at your option) any later version.
  12.  
  13.    CCres is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with CCres; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21.  */
  22.  
  23. #include "ccres.h"
  24.  
  25. #include <string.h>
  26.  
  27. #include <OSLib/ddeutils.h>
  28.  
  29. #include <OSLib/colourdbox.h>
  30. #include <OSLib/colourmenu.h>
  31. #include <OSLib/dcs.h>
  32. #include <OSLib/fileinfo.h>
  33. #include <OSLib/fontdbox.h>
  34. #include <OSLib/fontmenu.h>
  35. #include <OSLib/iconbar.h>
  36. #include <OSLib/menu.h>
  37. #include <OSLib/printdbox.h>
  38. #include <OSLib/proginfo.h>
  39. #include <OSLib/quit.h>
  40. #include <OSLib/saveas.h>
  41. #include <OSLib/scale.h>
  42. #include <OSLib/window.h>
  43.  
  44.  
  45. static CLASSES Classes[] = {
  46.     {ColourDbox_ClassSWI, colourdbox, _colourdbox, "colourdbox_object"},
  47.     {ColourMenu_ClassSWI, colourmenu, _colourmenu, "colourmenu_object"},
  48.     {DCS_ClassSWI       , dcs       , _dcs       , "dcs_object"       },
  49.     {FileInfo_ClassSWI  , fileinfo  , _fileinfo  , "fileinfo_object"  },
  50.     {FontDbox_ClassSWI  , fontdbox  , _fontdbox  , "fontdbox_object"  },
  51.     {FontMenu_ClassSWI  , fontmenu  , _fontmenu  , "fontmenu_object"  },
  52.     {Iconbar_ClassSWI   , iconbar   , _iconbar   , "iconbar_object"   },
  53.     {Menu_ClassSWI      , menu      , _menu      , "menu_object"      },
  54.     {PrintDbox_ClassSWI , printdbox , _printdbox , "printdbox_object" },
  55.     {ProgInfo_ClassSWI  , proginfo  , _proginfo  , "proginfo_object"  },
  56.     {Quit_ClassSWI      , quit      , _quit      , "quit_object"      },
  57.     {SaveAs_ClassSWI    , saveas    , _saveas    , "saveas_object"    },
  58.     {Scale_ClassSWI     , scale     , _scale     , "scale_object"     },
  59.     {Window_ClassSWI    , window    , _window    , "window_object"    }
  60. };
  61.  
  62.  
  63. static BOOL alloc_string_table(PSTRINGTABLE pTable)
  64. {
  65.     int cb;
  66.  
  67.     pTable->ref = pTable->max = 0;
  68.     cb = 2 * 256 * 256;        // 256 gadgets, 256 chars each, 2 strings per gadget
  69.     if ((pTable->pstr = MyAlloc(cb)) == NULL) {
  70.         return(FALSE);
  71.     }
  72.     pTable->max = cb;
  73.     return(TRUE);
  74. }
  75.  
  76.  
  77. static BOOL alloc_reloc_table(PRELOCTABLE pTable)
  78. {
  79.     int nReloc;
  80.  
  81.     pTable->ref = pTable->max = 0;
  82.     nReloc = 2 * 256;        // 256 gadgets, 2 strings per gadget
  83.     if ((pTable->pReloc = MyAlloc(nReloc * sizeof(RELOC))) == NULL) {
  84.         return(FALSE);
  85.     }
  86.     pTable->max = nReloc;
  87.     return(TRUE);
  88. }
  89.  
  90.  
  91. static void free_string_table(PSTRINGTABLE pTable)
  92. {
  93.     if (pTable->pstr != NULL) {
  94.         MyFree(pTable->pstr);
  95.     }
  96.     pTable->pstr = NULL;
  97.     pTable->ref = pTable->max = 0;
  98. }
  99.  
  100.  
  101. static void free_reloc_table(PRELOCTABLE pTable)
  102. {
  103.     if (pTable->pReloc != NULL) {
  104.         MyFree(pTable->pReloc);
  105.     }
  106.     pTable->pReloc = NULL;
  107.     pTable->ref = pTable->max = 0;
  108. }
  109.  
  110.  
  111. static BOOL text2res(PDATA data, PSTR pszOutFile)
  112. {
  113.     toolbox_resource_file_base Hdr;
  114.     FILE * hf;
  115.     PSTR pszIn, pszOut, pszEnd, pszObject;
  116.     int m;
  117.     BOOL fHeader;
  118.  
  119.     pszIn = data->pszIn;
  120.     pszEnd = data->pszIn + data->cbIn;
  121.     if (memcmp(pszIn, "RESF:1.01", 8) != 0) {
  122.         error("File is not RESF v1.01");
  123.         return(FALSE);
  124.     }
  125.     if ((pszOut = MyAlloc(296 * 268 * 3)) == NULL ||        // approx = window with 256 gadgets, 3 strings each
  126.                 !alloc_string_table(&data->StringTable) ||
  127.                 !alloc_string_table(&data->MessageTable) ||
  128.                 !alloc_reloc_table(&data->RelocTable)) {
  129.         error("Unable to allocate necessary memory");
  130.         return(FALSE);
  131.     } else if ((hf = fopen(pszOutFile, "wb")) == NULL) {
  132.         error("Unable to create output file '%s'", pszOutFile);
  133.         return(FALSE);
  134.     } else {
  135.         data->fThrowback = FALSE;
  136.         Hdr.file_id = RESF;
  137.         Hdr.version = 101;
  138.         Hdr.header_size = -1;
  139.         fHeader = FALSE;
  140.         while ((pszObject = next_object(&pszIn, pszEnd)) != NULL) {
  141. LOG(("Found '%s'", pszObject));
  142.             for (m = 0; m < ELEMENTS(Classes); m++) {
  143.                 if (__stricmp(Classes[m].name, pszObject) == 0 && Classes[m].t2o != NULL) {
  144.                     if (!fHeader) {
  145.                         Hdr.header_size = sizeof(Hdr);
  146.                         fwrite(&Hdr, sizeof(Hdr), 1, hf);
  147.                         fHeader = TRUE;
  148.                     }
  149.                     reset_string_table(&data->StringTable);
  150.                     reset_string_table(&data->MessageTable);
  151.                     reset_reloc_table(&data->RelocTable);
  152.                     _object(hf, data, pszIn, pszOut, &Classes[m]);
  153.                     goto text2res_added;
  154.                 }
  155.             }
  156.             error("Don't know how to handle object '%s'", pszObject);
  157.  
  158. text2res_added:
  159.  
  160.             if ((pszIn = object_end(data, pszIn, pszEnd)) == NULL) {
  161. LOG(("object_end returned NULL, so finished"));
  162.                 break;
  163.             }
  164.         }
  165.         if (!fHeader) {
  166.             fwrite(&Hdr, sizeof(Hdr), 1, hf);
  167.         }
  168.         fclose(hf);
  169.         osfile_set_type(pszOutFile, osfile_TYPE_RESOURCE);
  170.         if (data->fThrowback) {
  171.             ddeutils_throwback_end();
  172.             data->fThrowback = FALSE;
  173.         }
  174.         free_string_table(&data->StringTable);
  175.         free_string_table(&data->MessageTable);
  176.         free_reloc_table(&data->RelocTable);
  177.         MyFree(pszOut);
  178.     }
  179.     return(TRUE);
  180. }
  181.  
  182.  
  183. static BOOL res2text(PDATA data, PSTR pszOutFile)
  184. {
  185.     PINT relocation_table;
  186.     toolbox_resource_file_base * file_hdr;
  187.     toolbox_relocatable_object_base * obj, * end;
  188.     FILE * hf;
  189.     int cb, m;
  190.     BOOL fConverted;
  191.  
  192.     fConverted = FALSE;
  193.     file_hdr = (toolbox_resource_file_base *) data->pszIn;
  194.     if (file_hdr->file_id != RESF) {
  195.         error("Invalid Resource File Header (%x)", file_hdr->file_id);
  196.     }
  197.     if (file_hdr->version != 101) {
  198.         error("Unknown Resource File Version (%x)", file_hdr->version);
  199.     }
  200. //LOG(("file_id %x", file_hdr->file_id));
  201. //LOG(("version %d", file_hdr->version));
  202. //LOG(("header_size %d", file_hdr->header_size));
  203.     if ((hf = fopen(pszOutFile, "wb")) == NULL) {
  204.         error("Unable to create output file '%s'", pszOutFile);
  205.     } else {
  206.         fprintf(hf, "RESF:%d.%02d\n", file_hdr->version / 100, file_hdr->version % 100);
  207.         if (file_hdr->header_size > 0) {
  208.             obj = (toolbox_relocatable_object_base *) (file_hdr + 1);
  209.             end = (toolbox_relocatable_object_base *) &data->pszIn[data->cbIn];
  210.             do {
  211.                 fputs("\n", hf);
  212. LOG(("Finding class_no:%x", obj->rf_obj.class_no));
  213.                 for (m = 0; m < ELEMENTS(Classes); m++) {
  214.                     if (Classes[m].class_no == obj->rf_obj.class_no) {
  215.                         fprintf(hf, "%s {\n", Classes[m].name);
  216.                         object(hf, obj, Classes[m].o2t);
  217.                         fputs("}\n", hf);
  218.                         goto res2text_added;
  219.                     }
  220.                 }
  221.                 error("Unknown class '%s' (%x)", obj->rf_obj.name, obj->rf_obj.class_no);
  222.  
  223. res2text_added:
  224.  
  225.                 cb = sizeof(toolbox_relocatable_object_base) - sizeof(obj->rf_obj) + obj->rf_obj.size;
  226.                 if (obj->relocation_table_offset != -1) {
  227.                     relocation_table = (PINT) (((PSTR) obj) + obj->relocation_table_offset);
  228.                     cb += sizeof(int) * (1 + 2 * relocation_table[0]);
  229.                 }
  230. LOG(("Moving to next class by adding %d\n", cb));
  231.                 obj = (toolbox_relocatable_object_base *) (((PSTR) obj) + cb);
  232.             } while (cb != 0 && obj < end);
  233.         }
  234.         fclose(hf);
  235.         osfile_set_type(pszOutFile, osfile_TYPE_TEXT);
  236.         fConverted = TRUE;
  237.     }
  238.  
  239.     return(fConverted);
  240. }
  241.  
  242. #define template_NO_FONTS         (bits)-1
  243. #define template_TYPE_WINDOW    (bits)0x1u
  244.  
  245. typedef struct {
  246.     bits font_offset;
  247.     bits reserved[3];
  248. } template_header;
  249.  
  250. typedef struct {
  251.     bits offset;
  252.     bits size;
  253.     int type;
  254.     char name[12];
  255. } template_index;
  256.  
  257. typedef struct {
  258.     bits x_point_size;
  259.     bits y_point_size;
  260.     char font_name[40];
  261. } template_font_data;
  262.  
  263. static int window_count(PSTR pszIn, PSTR pszEnd, PINT pi)
  264. {
  265.     int d, w, i;
  266.     char ch, ch0;
  267.  
  268.     d = w = i = 0;
  269.     ch0 = '\0';
  270.     while(pszIn < pszEnd) {
  271.         if ((ch = *pszIn++) == ':' || ch == '\0') {
  272.             ch0 = ch;
  273.         } else if (ch0 == '\0') {
  274.             if (ch == '{') {
  275.                 if (d == 0) {
  276.                     w++;
  277.                 } else {
  278.                     i++;
  279.                 }
  280.                 d++;
  281.             } else if (ch == '}') {
  282.                 d--;
  283.             }
  284.         }
  285.     }
  286.     *pi = i;
  287.     return(w);
  288. }
  289.  
  290. static int icon_count(PSTR pszIn, PSTR pszEnd)
  291. {
  292.     int d, i;
  293.     char ch, ch0;
  294.  
  295.     d = 1;
  296.     i = 0;
  297.     ch0 = '\0';
  298.     while(pszIn < pszEnd && d > 0) {
  299.         if ((ch = *pszIn++) == ':' || ch == '\0') {
  300.             ch0 = ch;
  301.         } else if (ch0 == '\0') {
  302.             if (ch == '{') {
  303.                 i++;
  304.                 d++;
  305.             } else if (ch == '}') {
  306.                 d--;
  307.             }
  308.         }
  309.     }
  310.     return(i);
  311. }
  312.  
  313.  
  314. static OBJECTLIST TemplateFontDataList[] = {
  315.     {iol_BITS,  "x_point_size:",  offsetof(template_font_data, x_point_size), NULL,  0},
  316.     {iol_BITS,  "y_point_size:",  offsetof(template_font_data, y_point_size), NULL,  0},
  317.     {iol_PSTR,  "font_name:",     offsetof(template_font_data, font_name),    NULL, 40}
  318. };
  319.  
  320.  
  321. static void get_template_fonts(FILE * hf, template_font_data * font_data, template_font_data * end)
  322. {
  323.     template_font_data temp;
  324.     PSTR pszFrom;
  325.  
  326.     while (font_data < end) {
  327.         pszFrom = (PSTR) font_data;            // bug in memcpy? without this it does a word-aligned copy
  328.         memcpy(&temp, pszFrom, sizeof(temp));
  329.         fputs("\ntemplate_font_data {\n", hf);
  330.         get_objects(hf, NULL, NULL, (PSTR) &temp, TemplateFontDataList, ELEMENTS(TemplateFontDataList), 1);
  331.         fputs("}\n", hf);
  332.         font_data++;
  333.     }
  334. }
  335.  
  336.  
  337. static OBJECTLIST TemplateHeaderList[] = {
  338.     {iol_PSTR,  "template_name:",  offsetof(template_index, name), NULL, 12}
  339. };
  340.  
  341. static BOOL text2template(PDATA data, PSTR pszOutFile)
  342. {
  343.     template_font_data font_data;
  344.     template_header * header;
  345.     template_index * index, * i;
  346.     FILE * hf;
  347.     PINT pTerm;
  348.     PSTR pszIn, pszTemplate, pszOut, pszEnd, pszObject, pszBuff;
  349.     int cb, cbBuff, nWindows, nIcons;
  350.     BOOL fConverted;
  351.  
  352.     pszIn = data->pszIn;
  353.     pszEnd = data->pszIn + data->cbIn;
  354.     fConverted = FALSE;
  355.     if ((nWindows = window_count(pszIn, pszEnd, &nIcons)) > 0) {
  356. LOG(("Found %d windows and %d icons", nWindows, nIcons));
  357.         if ((pszTemplate = MyAlloc(sizeof(template_header) + sizeof(int) +
  358.                                nWindows * (sizeof(template_index) + sizeof(wimp_window) + (nIcons * (256 + sizeof(wimp_icon)))))) == NULL ||
  359.             !alloc_string_table(&data->StringTable)) {      // this is only required so that we can share put_string with Res files
  360.             error("Unable to allocate necessary memory");
  361.         } else {
  362.             if ((hf = fopen(pszOutFile, "wb")) == NULL) {
  363.                 error("Unable to create output file '%s'", pszOutFile);
  364.             } else {
  365.                 data->fThrowback = FALSE;
  366.                 header = (template_header *) pszTemplate;
  367.                 header->font_offset = template_NO_FONTS;
  368.                 index = (template_index *) (header + 1);
  369.                 pTerm = (PINT) (index + nWindows);
  370.                 pszOut = (PSTR) (pTerm + 1);
  371.                 pszBuff = NULL;
  372.                 cbBuff = 0;
  373.                 i = index;
  374.                 while ((pszObject = next_object(&pszIn, pszEnd)) != NULL && __stricmp(pszObject, "wimp_window") == 0) {
  375.                     nIcons = icon_count(pszIn, pszEnd);
  376. LOG(("Found '%s' (%d icons) pszOut=%p", pszObject, nIcons, pszOut));
  377.                     cb = sizeof(wimp_window) + (nIcons * (256 + sizeof(wimp_icon)));
  378.                     if (cbBuff < cb) {
  379.                         if (pszBuff != NULL) {
  380.                             MyFree(pszBuff);
  381.                         }
  382.                         if ((pszBuff = MyAlloc(cb)) == NULL) {
  383.                             error("Unable to allocate %d bytes", cb);
  384.                             break;
  385.                         }
  386.                         cbBuff = cb;
  387.                     }
  388.                     cb = _window_template(data, pszIn, -(sizeof(wimp_window_base) + nIcons * sizeof(wimp_icon)), (wimp_window_base *) pszBuff);
  389.                     memcpy(pszOut, pszBuff, cb);
  390.                     i->size = cb;
  391.                     i->offset = (int) (pszOut - pszTemplate);
  392.                     pszOut += cb;
  393.                     i->type = template_TYPE_WINDOW;
  394.                     put_objects(data, pszIn, 0, (PSTR) i, TemplateHeaderList, ELEMENTS(TemplateHeaderList));
  395. // template name is different to icon name because it always needs a terminator, which restricts it to 11 chars
  396. // to avoid having to write separate code, use the iol_PSTR data type then apply this bodge...
  397.                     if (i->name[11] >= ' ') {
  398.                         i->name[11] = '\0';
  399.                         report(data, pszObject, "Template name truncated to '%s'", i->name);
  400.                         i->name[11] = '\r';
  401.                     }
  402.                     i++;
  403.                     if ((pszIn = object_end(data, pszIn, pszEnd)) == NULL) {
  404. LOG(("object_end returned NULL, so finished"));
  405.                         break;
  406.                     }
  407.                 }
  408.                 pszIn = data->pszIn;
  409.                 while ((pszObject = next_object(&pszIn, pszEnd)) != NULL) {
  410.                     if (__stricmp(pszObject, "template_font_data") == 0) {
  411.                         if (header->font_offset == template_NO_FONTS) {
  412.                             header->font_offset = (bits) (pszOut - pszTemplate);
  413.                         }
  414. // make sure we're writing to a word-aligned structure...
  415.                         memset(&font_data, 0, sizeof(font_data));
  416.                         put_objects(data, pszIn, 0, (PSTR) &font_data, TemplateFontDataList, ELEMENTS(TemplateFontDataList));
  417.                         memcpy(pszOut, &font_data, sizeof(font_data));
  418.                         pszOut += sizeof(template_font_data);
  419.                     }
  420.                     if ((pszIn = object_end(data, pszIn, pszEnd)) == NULL) {
  421. LOG(("object_end returned NULL, so finished"));
  422.                         break;
  423.                     }
  424.  
  425.                 }
  426.                 fwrite(pszTemplate, (int) (pszOut - pszTemplate), 1, hf);
  427.                 fclose(hf);
  428.                 osfile_set_type(pszOutFile, osfile_TYPE_TEMPLATE);
  429.                 if (data->fThrowback) {
  430.                     ddeutils_throwback_end();
  431.                     data->fThrowback = FALSE;
  432.                 }
  433.                 if (pszBuff != NULL) {
  434.                     MyFree(pszBuff);
  435.                 }
  436.                 fConverted = TRUE;
  437.             }
  438.             MyFree(pszTemplate);
  439.             free_string_table(&data->StringTable);
  440.         }
  441.     }
  442.     return(fConverted);
  443. }
  444.  
  445.  
  446. static BOOL template2text(PDATA data, PSTR pszOutFile)
  447. {
  448.     template_header * template_hdr;
  449.     template_index * obj, * end;
  450.     PSTR pszBuff;
  451.     FILE * hf;
  452.     int cbBuff;
  453.  
  454.     if ((hf = fopen(pszOutFile, "wb")) == NULL) {
  455.         error("Unable to create output file '%s'", pszOutFile);
  456.         return(FALSE);
  457.     }
  458.     fputs("Template:\n", hf);
  459.  
  460.     pszBuff = NULL;
  461.     cbBuff = 0;
  462.     template_hdr = (template_header *) data->pszIn;
  463.     obj = (template_index *) (template_hdr + 1);
  464.     end = (template_index *) &data->pszIn[data->cbIn];
  465.     while (obj->offset != 0) {
  466.         if (cbBuff < obj->size) {
  467.             if (pszBuff != NULL) {
  468.                 MyFree(pszBuff);
  469.             }
  470.             if ((pszBuff = MyAlloc(obj->size)) == NULL) {
  471.                 error("Unable to allocate %d bytes", obj->size);
  472.                 break;
  473.             }
  474.         }
  475.         memcpy(pszBuff, data->pszIn + obj->offset, obj->size);
  476.         fputs("\nwimp_window {\n", hf);
  477.         get_objects(hf, NULL, NULL, (PSTR) obj, TemplateHeaderList, ELEMENTS(TemplateHeaderList), 1);
  478.         window_template(hf, pszBuff);
  479.         fputs("}\n", hf);
  480.         obj++;
  481.     }
  482.     if (template_hdr->font_offset != template_NO_FONTS) {
  483.         get_template_fonts(hf, (template_font_data *) (data->pszIn + template_hdr->font_offset), (template_font_data *) end);
  484.     }
  485.     fclose(hf);
  486.     osfile_set_type(pszOutFile, osfile_TYPE_TEXT);
  487.  
  488.     if (pszBuff != NULL) {
  489.         MyFree(pszBuff);
  490.     }
  491.  
  492.     return(TRUE);
  493. }
  494.  
  495.  
  496. BOOL convert(PDATA data, PSTR pszOutFile)
  497. {
  498.     bits in, out;
  499.  
  500.     if ((in = data->nFiletypeIn) == osfile_TYPE_TEXT) {
  501.         if ((out = data->nFiletypeOut) == osfile_TYPE_RESOURCE) {
  502.             return(text2res(data, pszOutFile));
  503.         } else if (out == osfile_TYPE_TEMPLATE) {
  504.             return(text2template(data, pszOutFile));
  505.         } else {
  506. LOG(("action_save_to_file - unknown nFiletypeOut(%03x)", data->nFiletypeOut));
  507.         }
  508.     } else if (in == osfile_TYPE_RESOURCE) {
  509.         return(res2text(data, pszOutFile));
  510.     } else if (in == osfile_TYPE_TEMPLATE) {
  511.         return(template2text(data, pszOutFile));
  512.     } else {
  513. LOG(("action_save_to_file - unknown nFiletypeIn(%03x)", data->nFiletypeIn));
  514.     }
  515.     return(FALSE);
  516. }
  517.